package com.verisette.ncos.web.utilities;

import java.awt.AlphaComposite;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

import javax.imageio.ImageIO;

import org.apache.log4j.Logger;

/**
 * This class will be helpful when you want to resize an image with decent quality.
 * @author SANTHOSH REDDY MANDADI
 * @since 20-April-2009
 * @version 2.0.7
 */
public class PerfectImageResizer 
{
	static Logger logger = Logger.getLogger(PerfectImageResizer.class);
	
	public static void createThumbnail(String sourceFile, String destFile, int targetWidth,int targetHeight) throws Exception
	{
		try{
			BufferedImage srcImg = ImageIO.read(new File(sourceFile));
			BufferedImage destImg = createThumbnail(srcImg, destFile.substring(destFile.lastIndexOf('.')+1), targetWidth, targetHeight);
			ImageIO.write(destImg, destFile.substring(destFile.lastIndexOf('.')+1), new FileOutputStream(destFile));
		} catch(IOException ioe){
			logger.error("", ioe);
			throw new Exception(ioe);			
		}
	}

	public static BufferedImage createThumbnail(BufferedImage sourceImg, String destFileExtension, int targetWidth, int targetHeight) throws Exception 
	{
		int iw = sourceImg.getWidth();
		int ih = sourceImg.getHeight();

		Object hint = RenderingHints.VALUE_INTERPOLATION_BILINEAR;
		int type = sourceImg.getType() == 0? BufferedImage.TYPE_INT_ARGB : sourceImg.getType();

		// First get down to no more than 2x in W & H
		while (iw > targetWidth*2 || ih > targetHeight*2) {
			iw = (iw > targetWidth*2) ? iw/2 : iw;
			ih = (ih > targetHeight*2) ? ih/2 : ih;
			sourceImg = scaleImage(sourceImg, type, hint, iw, ih);
		}

		// REMIND: Conservative approach:
		// first get W right, then worry about H

		// If still too wide - do a horizontal trilinear blend
		// of sourceImg and a half-width sourceImg
		if (iw > targetWidth) {
			int iw2 = iw/2;
			BufferedImage sourceImg2 = scaleImage(sourceImg, type, hint, iw2, ih);
			if (iw2 < targetWidth) {
				sourceImg = scaleImage(sourceImg, type, hint, targetWidth, ih);
				sourceImg2 = scaleImage(sourceImg2, type, hint, targetWidth, ih);
				interp(sourceImg2, sourceImg, iw-targetWidth, targetWidth-iw2);
			}
			sourceImg = sourceImg2;
			iw = targetWidth;
		}
		// iw should now be targetWidth or smaller

		// If still too tall - do a vertical trilinear blend
		// of sourceImg and a half-height sourceImg
		if (ih > targetHeight) {
			int ih2 = ih/2;
			BufferedImage sourceImg2 = scaleImage(sourceImg, type, hint, iw, ih2);
			if (ih2 < targetHeight) {
				sourceImg = scaleImage(sourceImg, type, hint, iw, targetHeight);
				sourceImg2 = scaleImage(sourceImg2, type, hint, iw, targetHeight);
				interp(sourceImg2, sourceImg, ih-targetHeight, targetHeight-ih2);
			}
			sourceImg = sourceImg2;
			ih = targetHeight;
		}
		// ih should now be targetHeight or smaller

		// If we are too small, then it was probably because one of
		// the dimensions was too small from the start.
		if (iw < targetWidth && ih < targetHeight) {
			sourceImg = scaleImage(sourceImg, type, hint, targetWidth, targetHeight);
		}
		//			ImageIO.write(sourceImg, destFile.substring(destFile.lastIndexOf('.')+1), new FileOutputStream(destFile));
		return sourceImg;

	}
	
	private static BufferedImage scaleImage(BufferedImage orig,int type,Object hint,int w, int h)
	{
		BufferedImage tmp = new BufferedImage(w, h, type);
		Graphics2D g2 = tmp.createGraphics();
		g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, hint);
		g2.drawImage(orig, 0, 0, w, h, null);
		g2.dispose();
		return tmp;
	}

	private static void interp(BufferedImage img1,BufferedImage img2,int weight1,int weight2)
	{
		float alpha = weight1;
		alpha /= (weight1 + weight2);
		Graphics2D g2 = img1.createGraphics();
		g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha));
		g2.drawImage(img2, 0, 0, null);
		g2.dispose();
	}
	public static void main(String[] args) throws Exception
	{
		String sourceFile="acu-final.jpg";
		BufferedImage img = ImageIO.read(new File(sourceFile));
		int iw = img.getWidth();
		int ih = img.getHeight();
		int targetWidth=74;
		double imgHeightPercentage=((double)targetWidth/(double)iw)*100;
		double imgTotalHeight=ih * (imgHeightPercentage/100);
		int targetHeight=(int)Math.round(imgTotalHeight);
		PerfectImageResizer.createThumbnail(sourceFile,"acu-finalt.jpg",targetWidth,targetHeight);
	}
}